package com.marquisx.tzdice.model;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;

import com.marquisx.common.utils.RandomUtils;
import com.marquisx.tzdice.R;
import com.marquisx.tzdice.Constants.RecordType;
import com.marquisx.tzdice.database.DiceActionDBAdapter;

public class DiceActionManager
{
	private static DiceActionManager instance;
	private Context context;
	private DiceActionDBAdapter dbAdapter;
	
	private List<DiceAction> defaultDiceActions = new ArrayList<DiceAction>();
	
	private DiceActionManager (Context context)
	{
		this.context = context;
		dbAdapter = new DiceActionDBAdapter(context);
	}
	
	public static DiceActionManager getInstance( Context context )
	{
		if( instance != null )
		{
			instance.setContext(context);
			return instance;
		}
		else
		{
			return new DiceActionManager(context);
		}
	}
	
	public void generateDiceActionResult(DiceAction action, DiceRecord record)
	{
		assert(record.getType() == RecordType.Roll);
		
		String formatResult = "";
		if( action.getTimes() == 1 )
		{//single-roll
			int rollResult = RandomUtils.getRandomInt(1, action.getDice()+1);
			formatResult = context.getResources().getString(R.string.roll_result_single);
			//%1$s throws %2$dD%3$d%4$s for [%5$s]. \n-Result:%6$d%7$s=%8$d\n
			formatResult = String.format(
					context.getResources().getString(R.string.roll_result_single), 
					record.getUsername(),
					action.getTimes(),
					action.getDice(),
					action.getFormattedOffset(true),
					action.getName(),
					rollResult,
					action.getFormattedOffset(true)
			);
		
			record.setResult( rollResult + action.getOffset() + "" );
		}
		else
		{//multi-roll
			int[] resultArray = RandomUtils.getRandomInts(1, action.getDice() + 1, action.getTimes());
			int total = 0;
			StringBuffer resultBuffer = new StringBuffer();
			for (int i = 0; i < resultArray.length; i++)
			{
				resultBuffer.append(resultArray[i]);
				total += resultArray[i];
				if (i != resultArray.length - 1) resultBuffer.append(", ");
			}
	
			String result = context.getResources().getString(R.string.roll_result_mutli);
			//%1$s throws %2$dD%3$d%4$s for [%5$s]. \n-Total:%6$d%7$s%8$d\n%9$s\n
			formatResult = String.format(result, 
					record.getUsername(), 						// roller's name
					action.getTimes(), 							// rolling times
					action.getDice(),							// dice type
					action.getFormattedOffset(true), 			// dice offset
					action.getName(), 							// action name
					total,										// sum of dice
					action.getFormattedOffset(true), 			// dice offset
					resultBuffer.toString() 					// rolling result
			);
			record.setResult( total + action.getOffset() + "" );
		}
		
		record.setContent(formatResult);
	}
	
	public int getActionNumber()
	{
		return getActionList().size();
	}
	
	public List<DiceAction> getActionList()
	{
		List<DiceAction> actionList = dbAdapter.open().getAllEntries();
		
		/*
		if(  actionList == null || actionList.size() == 0 )
		{
			actionList = getDefaultDiceActions();
			dbAdapter.insertEntries(actionList);
			//get action id info from db
			actionList = dbAdapter.getAllEntries();
		}*/
		
		dbAdapter.close();
		return actionList;
	}
	
	public List<DiceAction> getDefaultDiceActions()
	{
		defaultDiceActions.clear();
		
		defaultDiceActions.add(new DiceAction(
				getText(R.string.action_1_name), getText(R.string.action_1_description), 
				R.drawable.action_pic_001, 4, 1, 0, false, DiceAction.NO_THRESHOLD));
		defaultDiceActions.add(new DiceAction(
				getText(R.string.action_2_name), getText(R.string.action_2_description), 
				R.drawable.action_pic_031, 6, 1, 0, false, DiceAction.NO_THRESHOLD));
		defaultDiceActions.add(new DiceAction(
				getText(R.string.action_3_name), getText(R.string.action_3_description),  
				R.drawable.action_pic_071, 8, 1, 0, false, DiceAction.NO_THRESHOLD));
		defaultDiceActions.add(new DiceAction(
				getText(R.string.action_4_name), getText(R.string.action_4_description),  
				R.drawable.action_pic_042, 10, 1, 2, false, DiceAction.NO_THRESHOLD));
		defaultDiceActions.add(new DiceAction(
				getText(R.string.action_5_name), getText(R.string.action_5_description),  
				R.drawable.action_pic_058, 100, 2, 0, false, DiceAction.NO_THRESHOLD));
		
		return defaultDiceActions;
	}
	
	public void setContext(Context context)
	{
		this.context = context;
		dbAdapter = new DiceActionDBAdapter(context);
	}
	
	private String getText(int resId)
	{
		return context.getResources().getString(resId);
	}

	public void closeDB()
	{
		dbAdapter.close();
	}

	public void removeAllActions()
	{
		dbAdapter.open().deleteAll();
		dbAdapter.close();
	}

	public void addActions(List<DiceAction> actionList)
	{
		dbAdapter.open().insertEntries(actionList);
		dbAdapter.close();
	}
	
	public void addAction(DiceAction action)
	{
		dbAdapter.open().insertEntry(action);
		dbAdapter.close();
	}
	

	public void updateAction(DiceAction action)
	{
		dbAdapter.open().updateEntry(action);
		dbAdapter.close();
	}
	
	public void removeAction(DiceAction action)
	{
		dbAdapter.open().removeEntry(action);
		dbAdapter.close();
	}

	public DiceAction getAction(long actionId)
	{
		DiceAction action = dbAdapter.open().getEntry(actionId);
		dbAdapter.close();
		
		return action;
	}
}
